namespace DotNetNuke.Framework
{
    using DotNetNuke.Common;
    using DotNetNuke.Entities.Modules;
    using DotNetNuke.Entities.Portals;
    using DotNetNuke.Entities.Users;
    using DotNetNuke.Security.Permissions;
    using DotNetNuke.Services.Exceptions;
    using DotNetNuke.Services.Localization;
    using Microsoft.VisualBasic;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;

    public abstract class PageBase : Page
    {
        private ArrayList _localizedControls;
        private string _localResourceFile;

        /// <summary>
        /// <para>Constructor</para>
        /// </summary>
        public PageBase()
        {
            base.Error += new EventHandler(this.Page_Error);
            this._localizedControls = new ArrayList();
        }

        /// <summary>
        /// <para>GetControlAttribute looks a the type of control and does it's best to find an AttributeCollection.</para>
        /// </summary>
        /// <param name="c">Control to find the AttributeCollection on</param>
        /// <param name="affectedControls">ArrayList that hold the controls that have been localized. This is later used for the removal of the key attribute.</param>
        /// <returns>A string containing the key for the specified control or null if a key attribute wasn't found</returns>
        internal static string GetControlAttribute(Control c, ArrayList affectedControls)
        {
            System.Web.UI.AttributeCollection ac = null;
            string key = null;
            if (c is LiteralControl)
            {
                key = null;
                ac = null;
            }
            else if (c is WebControl)
            {
                WebControl w = (WebControl) c;
                ac = w.Attributes;
                key = ac[DotNetNuke.Services.Localization.Localization.KeyName];
            }
            else if (c is HtmlControl)
            {
                HtmlControl h = (HtmlControl) c;
                ac = h.Attributes;
                key = ac[DotNetNuke.Services.Localization.Localization.KeyName];
            }
            else if (c is UserControl)
            {
                UserControl u = (UserControl) c;
                ac = u.Attributes;
                key = ac[DotNetNuke.Services.Localization.Localization.KeyName];
            }
            else
            {
                PropertyInfo attributeProperty = c.GetType().GetProperty("Attributes", typeof(System.Web.UI.AttributeCollection));
                if (attributeProperty != null)
                {
                    ac = (System.Web.UI.AttributeCollection) attributeProperty.GetValue(c, null);
                    key = ac[DotNetNuke.Services.Localization.Localization.KeyName];
                }
            }
            if ((key != null) & (affectedControls != null))
            {
                affectedControls.Add(ac);
            }
            return key;
        }

        public bool HasTabPermission(string PermissionKey)
        {
            return TabPermissionController.HasTabPermission(this.PortalSettings.ActiveTab.TabPermissions, PermissionKey);
        }

        /// <summary>
        /// <para>IterateControls performs the high level localization for each control on the page.</para>
        /// </summary>
        private void IterateControls(ArrayList affectedControls)
        {
            this.IterateControls(this.Controls, affectedControls, null);
        }

        private void IterateControls(ControlCollection controls, ArrayList affectedControls, string ResourceFileRoot)
        {
            IEnumerator refObjectHelperL0=null;
            try
            {
                refObjectHelperL0 = controls.GetEnumerator();
                while (refObjectHelperL0.MoveNext())
                {
                    Control c = (Control) refObjectHelperL0.Current;
                    this.ProcessControl(c, affectedControls, true, ResourceFileRoot);
                }
            }
            finally
            {
                if (refObjectHelperL0 is IDisposable)
                {
                    (refObjectHelperL0 as IDisposable).Dispose();
                }
            }
        }

        protected override void OnInit(EventArgs e)
        {
            Thread.CurrentThread.CurrentUICulture = this.PageCulture;
            Thread.CurrentThread.CurrentCulture = this.PageCulture;
            DotNetNuke.Services.Localization.Localization.LocalizePortalSettings();
            base.OnInit(e);
        }

        /// <summary>
        /// <para>Render is called to render all the server controls. Just prior to rendering, the localization is performed.</para>
        /// <seealso cref="M:System.Web.UI.Control.Render(System.Web.UI.HtmlTextWriter)" />
        /// </summary>
        /// <param name="evt">An EventArgs that controls the event data.</param>
        protected override void OnPreRender(EventArgs evt)
        {
            this.Trace.Write("LocalizedPage::PreRender", string.Format("Performing substitutions for {0}", Thread.CurrentThread.CurrentUICulture.Name));
            base.OnPreRender(evt);
            this.IterateControls(this.Controls, this._localizedControls, this.LocalResourceFile);
        }

        private void Page_Error(object Source, EventArgs e)
        {
            Exception exc = this.Server.GetLastError();
            string strURL = DotNetNuke.Common.Globals.ApplicationURL();
            if (this.Request.QueryString["error"] != null)
            {
                strURL = strURL + Interaction.IIf(strURL.IndexOf("?") == -1, "?", "&").ToString() + "error=terminate";
            }
            else
            {
                strURL = strURL + Interaction.IIf(strURL.IndexOf("?") == -1, "?", "&").ToString() + "error=" + this.Server.UrlEncode(exc.Message);
                if (!DotNetNuke.Common.Globals.IsAdminControl())
                {
                    strURL = strURL + "&content=0";
                }
            }
            DotNetNuke.Services.Exceptions.Exceptions.ProcessPageLoadException(exc, strURL);
        }

        /// <summary>
        /// <para>ProcessControl peforms the high level localization for a single control and optionally it's children.</para>
        /// </summary>
        /// <param name="c">Control to find the AttributeCollection on</param>
        /// <param name="affectedControls">ArrayList that hold the controls that have been localized. This is later used for the removal of the key attribute.</param>
        /// <param name="includeChildren">If true, causes this method to process children of this controls.</param>
        internal void ProcessControl(Control c, ArrayList affectedControls, bool includeChildren, string ResourceFileRoot)
        {
            string key = GetControlAttribute(c, affectedControls);
            if (key != null)
            {
                string value = DotNetNuke.Services.Localization.Localization.GetString(key, ResourceFileRoot);
                if (c is Label)
                {
                    Label ctrl = (Label) c;
                    if (value != "")
                    {
                        ctrl.Text = value;
                    }
                }
                if (c is LinkButton)
                {
                    LinkButton ctrl = (LinkButton) c;
                    if (value != "")
                    {
                        IEnumerator refObjectHelperL0=null;
                        MatchCollection imgMatches = Regex.Matches(value, "<(a|link|img|script|input|form).[^>]*(href|src|action)=(\\\"|'|)(.[^\\\"']*)(\\\"|'|)[^>]*>", RegexOptions.IgnoreCase);
                        try
                        {
                            refObjectHelperL0 = imgMatches.GetEnumerator();
                            while (refObjectHelperL0.MoveNext())
                            {
                                Match _match = (Match) refObjectHelperL0.Current;
                                if (_match.Groups[_match.Groups.Count - 2].Value.IndexOf("~") != -1)
                                {
                                    string resolvedUrl = this.Page.ResolveUrl(_match.Groups[_match.Groups.Count - 2].Value);
                                    value = value.Replace(_match.Groups[_match.Groups.Count - 2].Value, resolvedUrl);
                                }
                            }
                        }
                        finally
                        {
                            if (refObjectHelperL0 is IDisposable)
                            {
                                (refObjectHelperL0 as IDisposable).Dispose();
                            }
                        }
                        ctrl.Text = value;
                    }
                }
                if (c is HyperLink)
                {
                    HyperLink ctrl = (HyperLink) c;
                    if (value != "")
                    {
                        ctrl.Text = value;
                    }
                }
                if (c is ImageButton)
                {
                    ImageButton ctrl = (ImageButton) c;
                    if (value != "")
                    {
                        ctrl.AlternateText = value;
                    }
                }
                if (c is Button)
                {
                    Button ctrl = (Button) c;
                    if (value != "")
                    {
                        ctrl.Text = value;
                    }
                }
                if (c is HtmlImage)
                {
                    HtmlImage ctrl = (HtmlImage) c;
                    if (value != "")
                    {
                        ctrl.Alt = value;
                    }
                }
                if (c is CheckBox)
                {
                    CheckBox ctrl = (CheckBox) c;
                    if (value != "")
                    {
                        ctrl.Text = value;
                    }
                }
                if (c is BaseValidator)
                {
                    BaseValidator ctrl = (BaseValidator) c;
                    if (value != "")
                    {
                        ctrl.ErrorMessage = value;
                    }
                }
                if (c is Image)
                {
                    Image ctrl = (Image) c;
                    if (value != "")
                    {
                        ctrl.AlternateText = value;
                    }
                }
            }
            if (c is RadioButtonList)
            {
                RadioButtonList ctrl = (RadioButtonList) c;
                int refIntHelperL0 = ctrl.Items.Count - 1;
                for (int i = 0; i <= refIntHelperL0; i++)
                {
                    key = ctrl.Items[i].Attributes[DotNetNuke.Services.Localization.Localization.KeyName];
                    if (key != null)
                    {
                        string value = DotNetNuke.Services.Localization.Localization.GetString(key, ResourceFileRoot);
                        if (value != "")
                        {
                            ctrl.Items[i].Text = value;
                        }
                    }
                }
            }
            if (c is DropDownList)
            {
                DropDownList ctrl = (DropDownList) c;
                int refIntHelperL1 = ctrl.Items.Count - 1;
                for (int i = 0; i <= refIntHelperL1; i++)
                {
                    key = ctrl.Items[i].Attributes[DotNetNuke.Services.Localization.Localization.KeyName];
                    if (key != null)
                    {
                        string value = DotNetNuke.Services.Localization.Localization.GetString(key, ResourceFileRoot);
                        if (value != "")
                        {
                            ctrl.Items[i].Text = value;
                        }
                    }
                }
            }
            if (c is Image)
            {
                Image ctrl = (Image) c;
                if (ctrl.ImageUrl.IndexOf("~") != -1)
                {
                    ctrl.ImageUrl = this.Page.ResolveUrl(ctrl.ImageUrl);
                }
            }
            if (c is HtmlImage)
            {
                HtmlImage ctrl = (HtmlImage) c;
                if (ctrl.Src.IndexOf("~") != -1)
                {
                    ctrl.Src = this.Page.ResolveUrl(ctrl.Src);
                }
            }
            if (c is HyperLink)
            {
                HyperLink ctrl = (HyperLink) c;
                if (ctrl.NavigateUrl.IndexOf("~") != -1)
                {
                    ctrl.NavigateUrl = this.Page.ResolveUrl(ctrl.NavigateUrl);
                }
                if (ctrl.ImageUrl.IndexOf("~") != -1)
                {
                    ctrl.ImageUrl = this.Page.ResolveUrl(ctrl.ImageUrl);
                }
            }
            if (includeChildren & c.HasControls())
            {
                if (c is PortalModuleBase)
                {
                    PortalModuleBase ctrl = (PortalModuleBase) c;
                    this.IterateControls(c.Controls, affectedControls, ctrl.LocalResourceFile);
                }
                else
                {
                    PropertyInfo pi = c.GetType().GetProperty("LocalResourceFile");
                    if ((((pi != null) && (pi.GetValue(c, null) != null)) ? 1 : 0) != 0)
                    {
                        this.IterateControls(c.Controls, affectedControls, pi.GetValue(c, null).ToString());
                    }
                    else
                    {
                        this.IterateControls(c.Controls, affectedControls, ResourceFileRoot);
                    }
                }
            }
        }

        /// <summary>
        /// <para>RemoveKeyAttribute remove the key attribute from the control. If this isn't done, then the HTML output will have 
        /// a bad attribute on it which could cause some older browsers problems.</para>
        /// </summary>
        /// <param name="affectedControls">ArrayList that hold the controls that have been localized. This is later used for the removal of the key attribute.</param>
        public static void RemoveKeyAttribute(ArrayList affectedControls)
        {
            if (affectedControls != null)
            {
                int refIntHelperL0 = affectedControls.Count - 1;
                for (int i = 0; i <= refIntHelperL0; i++)
                {
                    ((System.Web.UI.AttributeCollection) affectedControls[i]).Remove(DotNetNuke.Services.Localization.Localization.KeyName);
                }
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
            this.Trace.Write("LocalizedPage::Render", "Removing resourcekey attribute from controls");
            RemoveKeyAttribute(this._localizedControls);
            base.Render(htmlWriter);
            string html = stringWriter.ToString();
            int StartPoint = html.IndexOf("<input type=\"hidden\" name=\"__VIEWSTATE\"");
            if (StartPoint >= 0)
            {
                int EndPoint = html.IndexOf("/>", StartPoint) + 2;
                string ViewStateInput = html.Substring(StartPoint, EndPoint - StartPoint);
                html = html.Remove(StartPoint, EndPoint - StartPoint);
                int FormEndStart = html.IndexOf("</form>");
                if (FormEndStart >= 0)
                {
                    html = html.Insert(FormEndStart, ViewStateInput);
                }
            }
            writer.Write(html);
        }

        public void SetLanguage(string value)
        {
            HttpCookie cookie = null;
            try
            {
                cookie = this.Response.Cookies.Get("language");
            }
            catch (Exception exception1)
            {
                
                
            }
            if (cookie == null)
            {
                if (value != "")
                {
                    cookie = new HttpCookie("language", value);
                    this.Response.Cookies.Add(cookie);
                }
            }
            else
            {
                cookie.Value = value;
                this.Response.Cookies.Set(cookie);
                if (value == "")
                {
                    this.Response.Cookies.Remove("language");
                }
            }
        }

        public string LocalResourceFile
        {
            get
            {
                string[] page = this.Request.ServerVariables["SCRIPT_NAME"].Split(new char[] { '/' });
                if (this._localResourceFile == "")
                {
                    return (this.TemplateSourceDirectory + "/App_LocalResources/" + page[page.GetUpperBound(0)] + ".resx");
                }
                return this._localResourceFile;
            }
            set
            {
                this._localResourceFile = value;
            }
        }

        public CultureInfo PageCulture
        {
            get
            {
                LocaleCollection enabledLocales = DotNetNuke.Services.Localization.Localization.GetEnabledLocales();
                CultureInfo ci = null;
                string preferredLocale = "";
                string preferredLanguage = "";
                if (HttpContext.Current != null)
                {
                    try
                    {
                        preferredLocale = HttpContext.Current.Request["language"];
                        if (preferredLocale != "")
                        {
                            if (DotNetNuke.Services.Localization.Localization.LocaleIsEnabled(ref preferredLocale))
                            {
                                ci = new CultureInfo(preferredLocale);
                            }
                            else
                            {
                                preferredLanguage = preferredLocale.Split(new char[] { '-' })[0];
                            }
                        }
                    }
                    catch (Exception exception1)
                    {
                        
                        
                    }
                }
                if (ci == null)
                {
                    UserInfo objUserInfo = UserController.GetCurrentUserInfo();
                    if ((objUserInfo.UserID != -1) && (objUserInfo.Profile.PreferredLocale != ""))
                    {
                        if (DotNetNuke.Services.Localization.Localization.LocaleIsEnabled(ref preferredLocale))
                        {
                            ci = new CultureInfo(objUserInfo.Profile.PreferredLocale);
                        }
                        else if (preferredLanguage == "")
                        {
                            preferredLanguage = objUserInfo.Profile.PreferredLocale.Split(new char[] { '-' })[0];
                        }
                    }
                }
                if (((ci == null) && (HttpContext.Current != null)) && (HttpContext.Current.Request.UserLanguages != null))
                {
                    try
                    {
                        foreach (string userLang in HttpContext.Current.Request.UserLanguages)
                        {
                            string userlanguage = userLang.Split(new char[] { ';' })[0];
                            if (DotNetNuke.Services.Localization.Localization.LocaleIsEnabled(ref userlanguage))
                            {
                                ci = new CultureInfo(userlanguage);
                            }
                            else if (userLang.Split(new char[] { ';' })[0].IndexOf("-") != -1)
                            {
                                string templang = userLang.Split(new char[] { ';' })[0];
                                foreach (string _localeCode in enabledLocales.AllKeys)
                                {
                                    if (_localeCode.Split(new char[] { '-' })[0] == templang.Split(new char[] { '-' })[0])
                                    {
                                        ci = new CultureInfo(_localeCode);
                                        break;
                                    }
                                }
                            }
                            if (ci != null)
                            {
                                goto Label_02DD;
                            }
                        }
                    }
                    catch (Exception exception2)
                    {
                        ProjectData.SetProjectError(exception2);
                        
                    }
                }
            Label_02DD:
                if ((ci == null) & (preferredLanguage != ""))
                {
                    foreach (string _localeCode in enabledLocales.AllKeys)
                    {
                        if (_localeCode.Split(new char[] { '-' })[0] == preferredLanguage)
                        {
                            ci = new CultureInfo(_localeCode);
                            break;
                        }
                    }
                }
                if (ci == null)
                {
                    if (this.PortalSettings.DefaultLanguage == "")
                    {
                        if (enabledLocales.Count > 0)
                        {
                            DictionaryEntry refStructHelperS0 = enabledLocales[0];
                            ci = new CultureInfo(Conversions.ToString(refStructHelperS0.Key));
                        }
                        else
                        {
                            ci = new CultureInfo("en-US");
                        }
                    }
                    else
                    {
                        ci = new CultureInfo(this.PortalSettings.DefaultLanguage);
                    }
                }
                if (ci == null)
                {
                    ci = new CultureInfo("en-US");
                }
                this.SetLanguage(ci.Name);
                return ci;
            }
            set
            {
                Thread.CurrentThread.CurrentUICulture = this.PageCulture;
                Thread.CurrentThread.CurrentCulture = this.PageCulture;
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
        public DotNetNuke.Entities.Portals.PortalSettings PortalSettings
        {
            get
            {
                return PortalController.GetCurrentPortalSettings();
            }
        }
    }
}

